package com.example.michong.controller;

import com.alibaba.fastjson.JSONArray;
import com.example.michong.entity.ExcelExportTemplate;
import com.example.michong.entity.ExcelImportEntity;
import com.example.michong.result.JsonResult;
import com.example.michong.util.excel.ExcelUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.*;

@RequestMapping("/file")
@Api(value = "文件相关操作")
@RestController
@RefreshScope
public class FileFunction {

    @Value("${save.path}")//${dd.accessToken}
    private String path;

    /**
     * , @RequestPart("file1") MultipartFile file3, @RequestPart("photo") MultipartFile photo
     *
     * @param request
     * @return
     * @throws IOException
     * @throws ServletException
     */
    @ApiOperation("大部分文件上传")
    @PostMapping("/upload")
    public String readFile(HttpServletRequest request) throws IOException, ServletException {

        File dir = new File(path);
        // 判断当前目录是否存在
        if (!dir.exists()) {
            // 目录不存在，需要创建
            dir.mkdirs();
        }

        /*
        第一种 ： 使用 MultipartFile 封装好的 transferTo() 方法保存文件
        photo.transferTo(new File(path+photo.getOriginalFilename()));

        第二种 ：  使用 MultipartFile 字节流保存文件
         fileUtil(file3, String.valueOf(path));
 */
        //List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file1");

        // request.getParts() 获取的是全部参数（name,age,file1,file2），包括文件参数和非文件参数
        for (Part part : request.getParts()) {
            // 获取文件类型
            part.getContentType();
            // 获取文件大小
            part.getSize();
            // 获取文件名
            part.getSubmittedFileName();
            // 获取参数名 （name,age,file1,file2）
            part.getName();

            if (part.getContentType() != null) {
                //同名文件默认覆盖
                part.write(path + part.getSubmittedFileName());
            } else {
                // 可以获取文本参数值
                request.getParameter(part.getName());
            }
        }
/*
        for (MultipartFile file : files) {
            file.transferTo(new File(path+file.getOriginalFilename()));
        }*/
        return "success";
    }

    @ApiOperation(value = "二进制文件上传")
    @PostMapping("/binary/upload")
    public String upload2(HttpServletRequest request) throws IOException {
        ServletInputStream inputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            inputStream = request.getInputStream();

            fileOutputStream = new FileOutputStream(new File(path));

            int len;
            byte[] bytes = new byte[1024];
            while ((len = inputStream.read(bytes)) != -1) {
                fileOutputStream.write(bytes, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "上传失败";
        } finally {
            if (fileOutputStream != null) {
                fileOutputStream.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }

        }
        return "上传成功";
    }

    @ApiOperation(value = "文件下载")
    @GetMapping("/download")
    public void download(String fileName, HttpServletResponse response, boolean isOnLine) throws IOException {
        // 路径可以指定当前项目相对路径
        File file = new File(path+fileName);
        if (file.exists()) {
            FileInputStream fileInputStream = new FileInputStream(file);
            ServletOutputStream outputStream = response.getOutputStream();
            if (isOnLine) {
                response.setContentType("application/octet-stream");
                // 如果文件名为中文需要设置编码
                response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "utf8"));
            }
            byte[] bytes = new byte[1024];
            int len;
            while ((len = fileInputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, len);
            }
            outputStream.close();
            fileInputStream.close();
        }
    }
    @ApiOperation("网络资源下载")
    @GetMapping("/downLoadMusic")
    public void downloadNetworkFile(HttpServletResponse response,String fileUrl) throws IOException {
        URL url = new URL("https://profile.csdnimg.cn/7/F/1/3_m0_51620667");
        URLConnection urlConnection = url.openConnection();
        InputStream inputStream = urlConnection.getInputStream();
        ServletOutputStream outputStream = response.getOutputStream();
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileUrl.substring(fileUrl.lastIndexOf("/")+1), "utf8"));
        byte[] bytes = new byte[1024];
        int len;
        while ((len = inputStream.read(bytes)) != -1) {
            outputStream.write(bytes, 0, len);
        }
        outputStream.close();
        inputStream.close();
    }


    @ApiOperation("Excel导入")
    @PostMapping("/import")
    public JsonResult importToJson(@RequestPart("file") MultipartFile file) throws Exception {
        JSONArray array = ExcelUtils.readMultipartFile(file);
        System.out.println("导入数据为:" + array);
        return new JsonResult(array);
    }

    @ApiOperation("excel实体类接收")
    @PostMapping("/importV1")
    public JsonResult inportToEntity(@RequestPart("file") MultipartFile file) {
        List<ExcelImportEntity> entities = null;
        try {
            entities = ExcelUtils.readMultipartFile(file, ExcelImportEntity.class);
        } catch (Exception e) {
            return new JsonResult("403","解析失败");
        }
        for (ExcelImportEntity user : entities) {
            System.out.println(user.toString());
        }
        return new JsonResult(entities);
    }

    @ApiOperation("导入多sheet页面")
    @PostMapping("/importV2")
    public void upload(@RequestPart("file") MultipartFile file) throws Exception {
        Map<String, JSONArray> map = ExcelUtils.readFileManySheet(file);
        map.forEach((key, value) -> {
            System.out.println("Sheet名称：" + key);
            System.out.println("Sheet数据：" + value);
            System.out.println("----------------------");
        });
    }

    @ApiOperation("表格导出")
    @GetMapping("/export")
    public void export(HttpServletResponse response) {
        // 表头数据
        //ExcelUtils.COLUMN_MERGE 横向合并
        List<Object> head = Arrays.asList("姓名","年龄","性别",ExcelUtils.COLUMN_MERGE);
        //List<Object> head = Arrays.asList("姓名","年龄","性别",头像);

        // 用户1数据
        List<Object> user1 = new ArrayList<>();
        user1.add("诸葛亮");
        user1.add(60);
        user1.add("男");
        user1.add("https://profile.csdnimg.cn/A/7/3/3_sunnyzyq");
        //导出为图片

       /* try {
            user1.add(new URL("https://profile.csdnimg.cn/A/7/3/3_sunnyzyq"));
        } catch (MalformedURLException e) {
            e.printStackTrace();
            user1.add("https://profile.csdnimg.cn/A/7/3/3_sunnyzyq");
        }*/


        // 用户2数据
        List<Object> user2 = new ArrayList<>();
        //user2.add("大乔");
        // ExcelUtils.ROW_MERGE 纵向合并
        user2.add(ExcelUtils.ROW_MERGE);
        user2.add(28);
        user2.add("女");
        user2.add("https://profile.csdnimg.cn/6/1/9/0_m0_48717371");
        // 将数据汇总
        List<List<Object>> sheetDataList = new ArrayList<>();
        sheetDataList.add(head);
        sheetDataList.add(user1);
        sheetDataList.add(user2);
        //实现下拉列表 键为第几列(崇宁开始) 值为value数据
        Map<Integer, List<String>> pullDwonList = new HashMap<>(1);
        pullDwonList.put(2,Arrays.asList("男","女","emmm"));
        // 导出数据
        ExcelUtils.export(response,"用户表", sheetDataList,pullDwonList);
    }
    @ApiOperation("导出模板")
    @GetMapping("/export/template")
    public void exportTemplate(HttpServletResponse response) {
        ExcelUtils.exportTemplate(response, "用户表", ExcelExportTemplate.class);
        //是否导出模板数据 在实体类 注释中example属性添加
        //ExcelUtils.exportTemplate(response, "用户表", ExcelExportTemplate.class,true);
    }

    @ApiOperation("根据entity 的 list导出")
    @GetMapping("/export/entityList")
    public void exportEntityList(HttpServletResponse response){

        List<ExcelExportTemplate> excel = new ArrayList<>();

        ExcelUtils.export(response,"用户表",excel,ExcelExportTemplate.class);
    }
    /**
     * 导出多 Sheet 页实现
     */
    @ApiOperation("导出多 Sheet 页实现")
    @GetMapping("/exportManySheet")
    public void exportManySheet(HttpServletResponse response) {
        // 第 1 个 Sheet 页
        List<List<Object>> sheet1 = new ArrayList<>();
        List<Object> sheet1Head = new ArrayList<>();
        sheet1Head.add("姓名");
        sheet1Head.add("数学");
        sheet1Head.add("英语");
        sheet1.add(sheet1Head);
        List<Object> row1 = new ArrayList<>();
        row1.add("Jack");
        row1.add(85);
        row1.add(100);
        sheet1.add(row1);
        List<Object> row2 = new ArrayList<>();
        row2.add("Marry");
        row2.add(85);
        row2.add(100);
        sheet1.add(row2);
        // 第 2 个 Sheet 页
        List<List<Object>> sheet2 = new ArrayList<>();
        List<Object> sheet2Head = new ArrayList<>();
        sheet2Head.add("姓名");
        sheet2Head.add("音乐");
        sheet2Head.add("美术");
        sheet2.add(sheet2Head);
        List<Object> row01 = new ArrayList<>();
        row01.add("Jack");
        row01.add(77);
        row01.add(66);
        sheet2.add(row01);
        List<Object> row02 = new ArrayList<>();
        row02.add("Marry");
        row02.add(99);
        row02.add(88);
        sheet2.add(row02);
        // 将两个 Sheet 页添加到集合中
        Map<String, List<List<Object>>> sheets = new LinkedHashMap<>();
        sheets.put("文化课", sheet1);
        sheets.put("艺术课", sheet2);
        // 导出数据
        ExcelUtils.exportManySheet(response, "学生成绩表", sheets);
    }
}
